/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.cast.s3p.persistencia;

import com.cast.s3p.persistencia.exceptions.IllegalOrphanException;
import com.cast.s3p.persistencia.exceptions.NonexistentEntityException;
import com.cast.s3p.persistencia.exceptions.PreexistingEntityException;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.Persistence;

/**
 *
 * @author edgarin
 */
public class ProyectoJpaController implements Serializable {

    public ProyectoJpaController() {
        this.emf = Persistence.createEntityManagerFactory("s3pPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Proyecto proyecto) throws PreexistingEntityException, Exception {
        if (proyecto.getConceptoevaluacionCollection() == null) {
            proyecto.setConceptoevaluacionCollection(new ArrayList<Conceptoevaluacion>());
        }
        if (proyecto.getRevisaproyectoCollection() == null) {
            proyecto.setRevisaproyectoCollection(new ArrayList<Revisaproyecto>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Empleado empleado = proyecto.getEmpleado();
            if (empleado != null) {
                empleado = em.getReference(empleado.getClass(), empleado.getCodempleado());
                proyecto.setEmpleado(empleado);
            }
            Departamento departamento = proyecto.getDepartamento();
            if (departamento != null) {
                departamento = em.getReference(departamento.getClass(), departamento.getCodigo());
                proyecto.setDepartamento(departamento);
            }
            Collection<Conceptoevaluacion> attachedConceptoevaluacionCollection = new ArrayList<Conceptoevaluacion>();
            for (Conceptoevaluacion conceptoevaluacionCollectionConceptoevaluacionToAttach : proyecto.getConceptoevaluacionCollection()) {
                conceptoevaluacionCollectionConceptoevaluacionToAttach = em.getReference(conceptoevaluacionCollectionConceptoevaluacionToAttach.getClass(), conceptoevaluacionCollectionConceptoevaluacionToAttach.getConceptoevaluacionPK());
                attachedConceptoevaluacionCollection.add(conceptoevaluacionCollectionConceptoevaluacionToAttach);
            }
            proyecto.setConceptoevaluacionCollection(attachedConceptoevaluacionCollection);
            Collection<Revisaproyecto> attachedRevisaproyectoCollection = new ArrayList<Revisaproyecto>();
            for (Revisaproyecto revisaproyectoCollectionRevisaproyectoToAttach : proyecto.getRevisaproyectoCollection()) {
                revisaproyectoCollectionRevisaproyectoToAttach = em.getReference(revisaproyectoCollectionRevisaproyectoToAttach.getClass(), revisaproyectoCollectionRevisaproyectoToAttach.getRevisaproyectoPK());
                attachedRevisaproyectoCollection.add(revisaproyectoCollectionRevisaproyectoToAttach);
            }
            proyecto.setRevisaproyectoCollection(attachedRevisaproyectoCollection);
            em.persist(proyecto);
            if (empleado != null) {
                empleado.getProyectoCollection().add(proyecto);
                empleado = em.merge(empleado);
            }
            if (departamento != null) {
                departamento.getProyectoCollection().add(proyecto);
                departamento = em.merge(departamento);
            }
            for (Conceptoevaluacion conceptoevaluacionCollectionConceptoevaluacion : proyecto.getConceptoevaluacionCollection()) {
                Proyecto oldProyectoOfConceptoevaluacionCollectionConceptoevaluacion = conceptoevaluacionCollectionConceptoevaluacion.getProyecto();
                conceptoevaluacionCollectionConceptoevaluacion.setProyecto(proyecto);
                conceptoevaluacionCollectionConceptoevaluacion = em.merge(conceptoevaluacionCollectionConceptoevaluacion);
                if (oldProyectoOfConceptoevaluacionCollectionConceptoevaluacion != null) {
                    oldProyectoOfConceptoevaluacionCollectionConceptoevaluacion.getConceptoevaluacionCollection().remove(conceptoevaluacionCollectionConceptoevaluacion);
                    oldProyectoOfConceptoevaluacionCollectionConceptoevaluacion = em.merge(oldProyectoOfConceptoevaluacionCollectionConceptoevaluacion);
                }
            }
            for (Revisaproyecto revisaproyectoCollectionRevisaproyecto : proyecto.getRevisaproyectoCollection()) {
                Proyecto oldProyectoOfRevisaproyectoCollectionRevisaproyecto = revisaproyectoCollectionRevisaproyecto.getProyecto();
                revisaproyectoCollectionRevisaproyecto.setProyecto(proyecto);
                revisaproyectoCollectionRevisaproyecto = em.merge(revisaproyectoCollectionRevisaproyecto);
                if (oldProyectoOfRevisaproyectoCollectionRevisaproyecto != null) {
                    oldProyectoOfRevisaproyectoCollectionRevisaproyecto.getRevisaproyectoCollection().remove(revisaproyectoCollectionRevisaproyecto);
                    oldProyectoOfRevisaproyectoCollectionRevisaproyecto = em.merge(oldProyectoOfRevisaproyectoCollectionRevisaproyecto);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findProyecto(proyecto.getNombre()) != null) {
                throw new PreexistingEntityException("Proyecto " + proyecto + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Proyecto proyecto) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Proyecto persistentProyecto = em.find(Proyecto.class, proyecto.getNombre());
            Empleado empleadoOld = persistentProyecto.getEmpleado();
            Empleado empleadoNew = proyecto.getEmpleado();
            Departamento departamentoOld = persistentProyecto.getDepartamento();
            Departamento departamentoNew = proyecto.getDepartamento();
            Collection<Conceptoevaluacion> conceptoevaluacionCollectionOld = persistentProyecto.getConceptoevaluacionCollection();
            Collection<Conceptoevaluacion> conceptoevaluacionCollectionNew = proyecto.getConceptoevaluacionCollection();
            Collection<Revisaproyecto> revisaproyectoCollectionOld = persistentProyecto.getRevisaproyectoCollection();
            Collection<Revisaproyecto> revisaproyectoCollectionNew = proyecto.getRevisaproyectoCollection();
            List<String> illegalOrphanMessages = null;
            for (Conceptoevaluacion conceptoevaluacionCollectionOldConceptoevaluacion : conceptoevaluacionCollectionOld) {
                if (!conceptoevaluacionCollectionNew.contains(conceptoevaluacionCollectionOldConceptoevaluacion)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Conceptoevaluacion " + conceptoevaluacionCollectionOldConceptoevaluacion + " since its proyecto field is not nullable.");
                }
            }
            for (Revisaproyecto revisaproyectoCollectionOldRevisaproyecto : revisaproyectoCollectionOld) {
                if (!revisaproyectoCollectionNew.contains(revisaproyectoCollectionOldRevisaproyecto)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Revisaproyecto " + revisaproyectoCollectionOldRevisaproyecto + " since its proyecto field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (empleadoNew != null) {
                empleadoNew = em.getReference(empleadoNew.getClass(), empleadoNew.getCodempleado());
                proyecto.setEmpleado(empleadoNew);
            }
            if (departamentoNew != null) {
                departamentoNew = em.getReference(departamentoNew.getClass(), departamentoNew.getCodigo());
                proyecto.setDepartamento(departamentoNew);
            }
            Collection<Conceptoevaluacion> attachedConceptoevaluacionCollectionNew = new ArrayList<Conceptoevaluacion>();
            for (Conceptoevaluacion conceptoevaluacionCollectionNewConceptoevaluacionToAttach : conceptoevaluacionCollectionNew) {
                conceptoevaluacionCollectionNewConceptoevaluacionToAttach = em.getReference(conceptoevaluacionCollectionNewConceptoevaluacionToAttach.getClass(), conceptoevaluacionCollectionNewConceptoevaluacionToAttach.getConceptoevaluacionPK());
                attachedConceptoevaluacionCollectionNew.add(conceptoevaluacionCollectionNewConceptoevaluacionToAttach);
            }
            conceptoevaluacionCollectionNew = attachedConceptoevaluacionCollectionNew;
            proyecto.setConceptoevaluacionCollection(conceptoevaluacionCollectionNew);
            Collection<Revisaproyecto> attachedRevisaproyectoCollectionNew = new ArrayList<Revisaproyecto>();
            for (Revisaproyecto revisaproyectoCollectionNewRevisaproyectoToAttach : revisaproyectoCollectionNew) {
                revisaproyectoCollectionNewRevisaproyectoToAttach = em.getReference(revisaproyectoCollectionNewRevisaproyectoToAttach.getClass(), revisaproyectoCollectionNewRevisaproyectoToAttach.getRevisaproyectoPK());
                attachedRevisaproyectoCollectionNew.add(revisaproyectoCollectionNewRevisaproyectoToAttach);
            }
            revisaproyectoCollectionNew = attachedRevisaproyectoCollectionNew;
            proyecto.setRevisaproyectoCollection(revisaproyectoCollectionNew);
            proyecto = em.merge(proyecto);
            if (empleadoOld != null && !empleadoOld.equals(empleadoNew)) {
                empleadoOld.getProyectoCollection().remove(proyecto);
                empleadoOld = em.merge(empleadoOld);
            }
            if (empleadoNew != null && !empleadoNew.equals(empleadoOld)) {
                empleadoNew.getProyectoCollection().add(proyecto);
                empleadoNew = em.merge(empleadoNew);
            }
            if (departamentoOld != null && !departamentoOld.equals(departamentoNew)) {
                departamentoOld.getProyectoCollection().remove(proyecto);
                departamentoOld = em.merge(departamentoOld);
            }
            if (departamentoNew != null && !departamentoNew.equals(departamentoOld)) {
                departamentoNew.getProyectoCollection().add(proyecto);
                departamentoNew = em.merge(departamentoNew);
            }
            for (Conceptoevaluacion conceptoevaluacionCollectionNewConceptoevaluacion : conceptoevaluacionCollectionNew) {
                if (!conceptoevaluacionCollectionOld.contains(conceptoevaluacionCollectionNewConceptoevaluacion)) {
                    Proyecto oldProyectoOfConceptoevaluacionCollectionNewConceptoevaluacion = conceptoevaluacionCollectionNewConceptoevaluacion.getProyecto();
                    conceptoevaluacionCollectionNewConceptoevaluacion.setProyecto(proyecto);
                    conceptoevaluacionCollectionNewConceptoevaluacion = em.merge(conceptoevaluacionCollectionNewConceptoevaluacion);
                    if (oldProyectoOfConceptoevaluacionCollectionNewConceptoevaluacion != null && !oldProyectoOfConceptoevaluacionCollectionNewConceptoevaluacion.equals(proyecto)) {
                        oldProyectoOfConceptoevaluacionCollectionNewConceptoevaluacion.getConceptoevaluacionCollection().remove(conceptoevaluacionCollectionNewConceptoevaluacion);
                        oldProyectoOfConceptoevaluacionCollectionNewConceptoevaluacion = em.merge(oldProyectoOfConceptoevaluacionCollectionNewConceptoevaluacion);
                    }
                }
            }
            for (Revisaproyecto revisaproyectoCollectionNewRevisaproyecto : revisaproyectoCollectionNew) {
                if (!revisaproyectoCollectionOld.contains(revisaproyectoCollectionNewRevisaproyecto)) {
                    Proyecto oldProyectoOfRevisaproyectoCollectionNewRevisaproyecto = revisaproyectoCollectionNewRevisaproyecto.getProyecto();
                    revisaproyectoCollectionNewRevisaproyecto.setProyecto(proyecto);
                    revisaproyectoCollectionNewRevisaproyecto = em.merge(revisaproyectoCollectionNewRevisaproyecto);
                    if (oldProyectoOfRevisaproyectoCollectionNewRevisaproyecto != null && !oldProyectoOfRevisaproyectoCollectionNewRevisaproyecto.equals(proyecto)) {
                        oldProyectoOfRevisaproyectoCollectionNewRevisaproyecto.getRevisaproyectoCollection().remove(revisaproyectoCollectionNewRevisaproyecto);
                        oldProyectoOfRevisaproyectoCollectionNewRevisaproyecto = em.merge(oldProyectoOfRevisaproyectoCollectionNewRevisaproyecto);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                String id = proyecto.getNombre();
                if (findProyecto(id) == null) {
                    throw new NonexistentEntityException("The proyecto with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(String id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Proyecto proyecto;
            try {
                proyecto = em.getReference(Proyecto.class, id);
                proyecto.getNombre();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The proyecto with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Conceptoevaluacion> conceptoevaluacionCollectionOrphanCheck = proyecto.getConceptoevaluacionCollection();
            for (Conceptoevaluacion conceptoevaluacionCollectionOrphanCheckConceptoevaluacion : conceptoevaluacionCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Proyecto (" + proyecto + ") cannot be destroyed since the Conceptoevaluacion " + conceptoevaluacionCollectionOrphanCheckConceptoevaluacion + " in its conceptoevaluacionCollection field has a non-nullable proyecto field.");
            }
            Collection<Revisaproyecto> revisaproyectoCollectionOrphanCheck = proyecto.getRevisaproyectoCollection();
            for (Revisaproyecto revisaproyectoCollectionOrphanCheckRevisaproyecto : revisaproyectoCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Proyecto (" + proyecto + ") cannot be destroyed since the Revisaproyecto " + revisaproyectoCollectionOrphanCheckRevisaproyecto + " in its revisaproyectoCollection field has a non-nullable proyecto field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Empleado empleado = proyecto.getEmpleado();
            if (empleado != null) {
                empleado.getProyectoCollection().remove(proyecto);
                empleado = em.merge(empleado);
            }
            Departamento departamento = proyecto.getDepartamento();
            if (departamento != null) {
                departamento.getProyectoCollection().remove(proyecto);
                departamento = em.merge(departamento);
            }
            em.remove(proyecto);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Proyecto> findProyectoEntities() {
        return findProyectoEntities(true, -1, -1);
    }

    public List<Proyecto> findProyectoEntities(int maxResults, int firstResult) {
        return findProyectoEntities(false, maxResults, firstResult);
    }

    private List<Proyecto> findProyectoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Proyecto.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Proyecto findProyecto(String id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Proyecto.class, id);
        } finally {
            em.close();
        }
    }

    public int getProyectoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Proyecto> rt = cq.from(Proyecto.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
